﻿using System;
using System.Device.Location;
using System.Threading;
using WP7Client.Helpers;
using WP7Client.ServerManager;
using WP7Client.Classes;
using MSH.Common.DAO.Results;
using MSH.Common.Classes;
using LocationServiceSample;
using System.Globalization;
using MSH.Common.DAO;
using System.Windows;

namespace WP7Client.Managers
{
    /// <summary>
    /// De locationmanager is verantwoordelijk voor het updaten van locatie op een instelbare interval
    /// </summary>
    public static class LocationManager
    {
        public static IGeoPositionWatcher<GeoCoordinate> Watcher;
        public static String Longitude;
        public static String Latitude;
        public static UserLocationData CurrentLocationData;
        private static Timer Timer;

        /// <summary>
        /// Start de locatie update manager
        /// </summary>
        public static void Start()
        {
            Random rnd = new Random();
            double latitude = rnd.Next(-90, 90);
            double longitude = rnd.Next(-180, 180);

            GeoCoordinateEventMock[] events = new GeoCoordinateEventMock[] {  
                new  GeoCoordinateEventMock { Latitude=52.10319, Longitude=5.10604, Time=new TimeSpan(0,0,1) }
                //new  GeoCoordinateEventMock { Latitude=latitude, Longitude=longitude, Time=new TimeSpan(0,0,1) }
            };

            if (System.Diagnostics.Debugger.IsAttached)
                Watcher = new EventListGeoLocationMock(events);
            else
                Watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);

            Watcher.PositionChanged += watcher_PositionChanged;

            Int32 interval = ControllerHelper.SettingController.GPSInterval;
            if (interval == 0)
                interval = (10000 * 1);
            Timer = new Timer(new TimerCallback(timerFired), null, 0, interval);
        }

        /// <summary>
        /// Stop de manager
        /// </summary>
        public static void Stop()
        {
            if(Watcher != null)
                Watcher.Stop();

            Watcher = null;
            Timer = null;
        }

        /// <summary>
        /// Stuur de locatie wijziging door naar de server
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            NumberFormatInfo numberFormatter = new CultureInfo("nl-NL").NumberFormat;
            Longitude = Convert.ToString(e.Position.Location.Longitude, numberFormatter);
            Latitude = Convert.ToString(e.Position.Location.Latitude, numberFormatter);

            double HA = e.Position.Location.HorizontalAccuracy;
            double VA = e.Position.Location.VerticalAccuracy;
            
            HttpGet locationHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "UpdateLocation/{0}/{1}/{2}", UserHelper.Token, Latitude, Longitude), typeof(UpdateLocationResult));
            locationHttpGet.FinishedGet += new EventHandler(locationHttpGet_FinishedGet);
        }

        /// <summary>
        /// Als resultaat komt er een UpdateLocationResult terug met daarin gegevens van de locatie in tekst
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void locationHttpGet_FinishedGet(Object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get == null || get.resultObject == null)
                    return;

                UpdateLocationResult locationResult = ((UpdateLocationResult)get.resultObject);
                if (locationResult.TokenValidationResult == TokenValidationResultEnum.Valid)
                {
                    CurrentLocationData = new UserLocationData(locationResult.Location.Latitude, locationResult.Location.Longitude);
                    CurrentLocationData.AddressLine = locationResult.Location.AddressLine;
                    CurrentLocationData.AdminDistrict = locationResult.Location.AdminDistrict;
                    CurrentLocationData.CountryRegion = locationResult.Location.CountryRegion;
                    CurrentLocationData.Locality = locationResult.Location.Locality;
                    CurrentLocationData.PostalCode = locationResult.Location.PostalCode;
                    ControllerHelper.OverviewController.CurrentLocation = CurrentLocationData;
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if(Watcher != null)
                    Watcher.Stop();
            }
        }

        /// <summary>
        /// Veranderen van de interval tussen de locatie updates
        /// </summary>
        /// <param name="time">Nieuwe interval in milliseconden</param>
        public static void ChangeTimerInterval(Int32 time)
        {
            Timer.Change(0, time);
        }

        /// <summary>
        /// De locatie moet geupdate worden omdat de timer verlopen is
        /// </summary>
        /// <param name="state"></param>
        private static void timerFired(object state)
        {
            Watcher.TryStart(false, new TimeSpan(0,1,0));
        }
    }
}
